package com.joeljhou.project.core.listener;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.joeljhou.project.core.data.DataListener;
import com.joeljhou.project.form.Component;
import com.joeljhou.project.pojo.ReportData;
import com.joeljhou.project.pojo.ReportFlatData;
import com.joeljhou.project.pojo.ReportHead;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
public class SaveListener implements ActionListener {

    //格式化日期
    private static final SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    //数据格式化
    private static final DecimalFormat DATA_FORMAT = new DecimalFormat("#.###");

    private String lastUsedDirectory;

    public SaveListener() {
        String desktopPath = System.getProperty("user.home") + File.separator + "Desktop\\";
        this.lastUsedDirectory = desktopPath;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // 处理按钮点击事件
        Component component = Component.getInstance();
        JFrame frame = component.getJFrame();
        JTextPane dataArea = component.getDataArea();
        //文本域数据为空，不做保存操作
        if (dataArea.getText().equals("")) {
            component.printLog("数据为空");
            return;
        }

        //保存文本文件
        saveExcelFile(component, frame, dataArea);
    }

    private void saveExcelFile(Component component, JFrame frame, JTextPane dataArea) {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
        String fileName = now.format(formatter) + ".xlsx";

        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setSelectedFile(new File(lastUsedDirectory + fileName));  // 指定保存文件的名称和路径
        int result = fileChooser.showSaveDialog(frame);      // 显示保存文件的对话框
        if (result == JFileChooser.APPROVE_OPTION) {         // 如果用户单击了保存按钮
            File file = fileChooser.getSelectedFile();       // 获取选择的文件
            // 记录下这个路径，以便下一次使用
            lastUsedDirectory = file.getParent() + "\\";

            String fileNamePath = file.getAbsolutePath();
            file.delete();

            ClassPathResource resource = new ClassPathResource("/excel/template.xlsx");
            try (ExcelWriter excelWriter = EasyExcel.write(fileNamePath)
                    .withTemplate(resource.getInputStream())
                    .excelType(ExcelTypeEnum.XLSX)
                    //写监听
                    .registerWriteHandler(new ExcelWriteStyleListener())
                    .build()) {
                WriteSheet writeSheet = EasyExcel.writerSheet().build();

                // 写入list之前的数据
                //Header
                String machine = component.getMachineTypeTextField().getText();  //打扣机型
                String buckle = component.getBuckleModelTextField().getText();   //扣子型号
                String cloth = component.getBuYuanTextField().getText();         //布原(mm)
                String date = DATETIME_FORMAT.format(new Date());                //送检日期
                String auditor = component.getAuditorTextField().getText();      //审批人
                String operator = component.getTesterTextField().getText();      //送检员
                ReportHead head = new ReportHead(machine, buckle, cloth, date, auditor, operator);
                excelWriter.fill(head, writeSheet);

                // 直接写入数据
                //Body
                List<ReportData> listData = DataListener.listData;
                excelWriter.fill(convertExcelData(listData), writeSheet);

                //最大值，最小值，平均值，总数量，良品数，非良品数
                Map<String, String> map = DataListener.mapStatistics;
                excelWriter.fill(statisticalData(map), writeSheet);
                excelWriter.finish();
            } catch (Exception e) {
                component.printLog("generate excel file error", Color.BLACK);
            }
        }
    }

    private static List<ReportFlatData> convertExcelData(List<ReportData> list) {
        //分为三个桶
        int bucketLine = (int) Math.ceil(list.size() / 3.0);
        List<List<ReportData>> buckets = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            int startIndex = i * bucketLine;
            int endIndex = Math.min((i + 1) * bucketLine, list.size());
            buckets.add(list.subList(startIndex, endIndex));
        }

        //共有bucketSize行数
        List<ReportFlatData> resultList = new ArrayList<>();
        for (int i = 0; i < bucketLine; i++) {
            ReportFlatData flatData = new ReportFlatData();
            //每行记录都从三个桶下提取数据
            for (int b = 0; b < 3; b++) {
                try {
                    ReportData reportData = buckets.get(b).get(i);
                    String testDate = reportData.getDate();
                    String pullValue = DATA_FORMAT.format(reportData.getValue() / 1000.0);
                    if (b == 0) {
                        flatData.setTestDate1(testDate);
                        flatData.setPull1(pullValue);
                    }
                    if (b == 1) {
                        flatData.setTestDate2(testDate);
                        flatData.setPull2(pullValue);
                    }
                    if (b == 2) {
                        flatData.setTestDate3(testDate);
                        flatData.setPull3(pullValue);
                    }
                } catch (Exception e) {
                    continue;
                }
            }
            resultList.add(flatData);
        }
        return resultList;
    }

    private List<ReportFlatData> statisticalData(Map<String, String> map) {
        List<ReportFlatData> list = new ArrayList<>();
        list.add(new ReportFlatData("最   大   值：", map.get("max")));
        list.add(new ReportFlatData("最   小   值：", map.get("min")));
        list.add(new ReportFlatData("平   均   值：", map.get("avg")));
        list.add(new ReportFlatData("良   品   数：", map.get("good")));
        list.add(new ReportFlatData("非 良 品 数：", map.get("bag")));
        return list;
    }

    public static void main(String[] args) {
        List<ReportData> list = new ArrayList<>();
        list.add(new ReportData("1", 1));
        list.add(new ReportData("2", 2));
        list.add(new ReportData("3", 3));
        list.add(new ReportData("4", 4));
        list.add(new ReportData("5", 5));
        list.add(new ReportData("6", 6));
        list.add(new ReportData("7", 7));
        list.add(new ReportData("8", 8));
        //list.add(new ReportData("9", 9));
        convertExcelData(list).forEach(System.out::println);
    }
}
